package com.mg.message.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mg.common.vo.ResponseResult;
import com.mg.common.vo.ResponseStatus;
import com.mg.message.entity.Message;
import com.mg.message.entity.MessageInterval;
import com.mg.message.mapper.MessageIntervalMapper;
import com.mg.message.mapper.MessageMapper;
import com.mg.message.service.MessageService;
import com.mg.message.vo.PageUtils;
import com.mg.message.vo.RequestMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;
import java.util.List;

@Service
@Slf4j
public class MessageServiceImpl implements MessageService {
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private MessageIntervalMapper messageIntervalMapper;

    @Override
    public ResponseResult<PageUtils<List<Message>>> getMessages(int currentPage, int pageSize) {
        ResponseResult<PageUtils<List<Message>>> entity = null;
        try {
            /**
             * 功能：短信总览，分页显示（使用MybatisPlus的分页插件）
             * 业务逻辑：
             * 1、返回当前页
             * 2、返回总条数
             * 3、返回当前页数据
             */
            Page<Message> messagePage = new Page<>();
            messagePage.setCurrent(currentPage);
            messagePage.setSize(pageSize);

            QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();

            messageQueryWrapper.select(Message.COL_MID, Message.COL_TITLE, Message.COL_CONTENT,
                    Message.COL_SEND_AREA, Message.COL_SEND_METHOD, Message.COL_TRIAL, Message.COL_TOTAL_PAY)
                    .eq(Message.COL_IS_DELETE,0);
            Page<Message> paegs = messageMapper.selectPage(messagePage, messageQueryWrapper);

            if (paegs != null) {
                PageUtils<List<Message>> messagePageUtils = new PageUtils<>();
                messagePageUtils.setCurrentPage(currentPage);
                messagePageUtils.setPageSize(pageSize);
                messagePageUtils.setTotalCount((int) paegs.getTotal());
                messagePageUtils.setData(paegs.getRecords());

                entity = ResponseResult.ok(messagePageUtils);
            } else {
                entity = ResponseResult.error(ResponseStatus.FAIL);
            }

        } catch (Exception e) {
            entity = ResponseResult.error(ResponseStatus.FAIL);
        }

        return entity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Integer> createMessage(RequestMessage requestMessage) {
        ResponseResult<Integer> entity = null;
        try {
            /**
             * 功能：新建短信
             * 业务逻辑：
             * 1、往短信主表插入一条记录，返回插入后的主键（MyBatisPlus的自带insert()方法可以实现）
             * 2、如果短信的发送方式是定时发送，要往定时器表中添加定时器规则
             * 3、如果短信的发送范围是群发，需要在前端选择发送的人群，并计算出总费用用于添加到短信主表（调用另一个接口实现）
             */
            Message message = new Message();
            BeanUtils.copyProperties(requestMessage, message);
            int count1 = messageMapper.insert(message);
            log.info(message.getMid()+"");

            //如果是定时发送，插入定时发送信息表
            if (requestMessage.getSendMethod() == 1) {
                MessageInterval messageInterval = new MessageInterval();
                BeanUtils.copyProperties(requestMessage, messageInterval);
                messageInterval.setMid(message.getMid());       //注意：关联新建信息的id
                int count2 = messageIntervalMapper.insert(messageInterval);
                if (count2 == 0) {
                    log.error("定时发送添加错误，请检查！");
                    //抛出异常，进行回滚
                    throw new RuntimeException(ResponseStatus.FAIL.getMsg());
                }
            }

            if (count1 != 0) {
                entity = ResponseResult.ok(count1);
            } else {
                throw new RuntimeException(ResponseStatus.FAIL.getMsg());
            }

            //如果是群发，需要选择范围
//            if (requestMessage.getSendArea() == 0) {
//            }

        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error(ResponseStatus.FAIL);
        }
        return entity;
    }

    @Override
    public ResponseResult<RequestMessage> getMessageDetail(int id) {
        ResponseResult<RequestMessage> entity = null;
        try {
            /**
             * 功能：查看短信详情
             * 业务逻辑：
             * 1、通过传递的短信表id查询
             * 2、短信表和定时器表的双表查询
             */
            RequestMessage requestMessage = messageMapper.selectMessageDetail(id);
            if (!StringUtils.isEmpty(requestMessage)) {
                entity = ResponseResult.ok(requestMessage);
            } else {
                entity = ResponseResult.error(ResponseStatus.FAIL);
            }
        } catch (Exception e) {
            entity = ResponseResult.error(ResponseStatus.FAIL);
        }
        return entity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Integer> updateMessage(RequestMessage requestMessage) {
        ResponseResult<Integer> entity = null;
        try {
            /**
             * 功能：修改短信详情
             * 业务逻辑：
             * 0、回显时，mid应该只是用于辅助查询的字段，应该是禁用的
             * 1、trial字段是禁用的，回显时应该前端禁止修改，后台手写的sql也没有trial的修改字段
             * 2、修改了发送范围，总费用应该自动变动，也是在前端禁止修改，由后台另一个接口计算得出
             * 3、修改了发送方式，为定时发送时要修改定时器，由定时发送修改为立即发送时，要去除定时器
             * 4、已经发送的短信不能更新，即trial==1，应该在前端设置禁止修改状态
             */
            Integer mid = requestMessage.getMid();
            ResponseResult<RequestMessage> messageDetail = getMessageDetail(mid);
            RequestMessage data = messageDetail.getData();

            //0：待审核   1：审核通过  2：审核不通过
            if (data.getTrial() == 1) {
                throw new RuntimeException();
            }

            Message message = new Message();
            BeanUtils.copyProperties(requestMessage, message);

            //修改发送范围
//            if (data.getSendArea() != requestMessage.getSendArea()) {
//                if (requestMessage.getSendArea() == 0) {
                    //总费用在零一个接口计算得出，在点击修改按钮时，已经有现成的数据
//                }
//            }

            //修改发送方式(0 立即发送 1 定时发送)
            //修改方式发生改变
            if (data.getSendMethod() != requestMessage.getSendMethod()) {
                if (requestMessage.getSendMethod() == 0) {
                    //修改为立即发送，去除定时器
                    QueryWrapper<MessageInterval> qw = new QueryWrapper<>();
                    qw.eq(MessageInterval.COL_MID, requestMessage.getMid());

                    int countDel = messageIntervalMapper.delete(qw);
                    if (countDel == 0) {
                        throw new RuntimeException();
                    }
                } else {
                    //修改为定时发送状态，添加定时器
                    MessageInterval messageInterval = new MessageInterval();
                    BeanUtils.copyProperties(requestMessage, messageInterval);
                    messageInterval.setMid(requestMessage.getMid());       //注意：关联新建信息的id
                    int count1 = messageIntervalMapper.insert(messageInterval);
                    if (count1 == 0) {
                        throw new RuntimeException(ResponseStatus.FAIL.getMsg());
                    }
                }
            } else {
                //修改方式没有改变，但修改了定时器
                if (requestMessage.getSendMethod() == 1) {
                    if (!requestMessage.getStartTime().equals(data.getStartTime()) || !requestMessage.getEndTime().equals(data.getEndTime()) || !requestMessage.getSendTime().equals(data.getSendTime())) {
                        //根据mid修改定时器
                        MessageInterval messageInterval = new MessageInterval();
                        BeanUtils.copyProperties(requestMessage, messageInterval);
                        int count2 = messageIntervalMapper.updateIntervalByMid(requestMessage.getMid(), messageInterval);
                        if (count2 == 0) {
                            throw new RuntimeException(ResponseStatus.FAIL.getMsg());
                        }
                    }
                }
            }

            //修改短信主表
            int count = messageMapper.updateMessageDetail(message);
            if (count == 0) {
                throw new RuntimeException(ResponseStatus.FAIL.getMsg());
            }
            entity = ResponseResult.ok(1);

        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseResult.error(ResponseStatus.FAIL);
        }

        return entity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Integer> delMessage(int mid) {
        ResponseResult<Integer> entity = null;
        try {
            /**
             * 功能：删除单条短信
             * 业务逻辑：
             * 1、使用假删除
             * 2、已经是发送状态的短信不能删除，即trial==1
             * 3、如果删除的短信绑定了定时器，连同定时器一起删除
             */
            ResponseResult<RequestMessage> messageDetail = getMessageDetail(mid);
            RequestMessage data = messageDetail.getData();

            if (data.getTrial() == 1) {
                throw new RuntimeException();
            }

            //定时器删除逻辑
            QueryWrapper<MessageInterval> messageIntervalQueryWrapper = new QueryWrapper<>();
            messageIntervalQueryWrapper.eq(MessageInterval.COL_MID, mid);
            Integer countInterval = messageIntervalMapper.selectCount(messageIntervalQueryWrapper);
            if (countInterval != 0) {
                int delCount = messageIntervalMapper.delete(messageIntervalQueryWrapper);
                //定时器删除失败
                if (delCount == 0) {
                    throw new RuntimeException();
                }
            }

            //假删除短信主表记录
            int count1 = messageMapper.deleteById(mid);
            if (count1 != 1) {
                throw new RuntimeException();
            } else {
                entity = ResponseResult.ok(count1);
            }

        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            entity = ResponseResult.error(ResponseStatus.FAIL);
        }

        return entity;
    }

}
